package com.shitou.shitouorder.listener;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rabbitmq.client.Channel;
import com.shitou.shitoucommons.exception.RRException;
import com.shitou.shitoucommons.utils.AllSaltEnum;
import com.shitou.shitoucommons.utils.RespBean;
import com.shitou.shitoucommons.vo.*;
import com.shitou.shitouorder.config.RabbitMQConfig;
import com.shitou.shitouorder.entity.OrderEntity;
import com.shitou.shitouorder.entity.OrderItemEntity;
import com.shitou.shitouorder.entity.PaymentInfoEntity;
import com.shitou.shitouorder.feign.SpuInfoFeign;
import com.shitou.shitouorder.service.OrderItemService;
import com.shitou.shitouorder.service.OrderService;
import com.shitou.shitouorder.service.PaymentInfoService;
import com.shitou.shitouorder.service.impl.OrderServiceImpl;
import com.shitou.shitouorder.vo.DeleteOrderVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * class detail:
 *
 * @author 石头人
 */
@SuppressWarnings("all")
@Slf4j
@Transactional
@Component
public class OrderListener {

    @Autowired
    private SpuInfoFeign spuInfoFeign;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    @Qualifier("RedisTemplate")
    private RedisTemplate redisTemplate;
    @Autowired
    private OrderService orderService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private PaymentInfoService paymentInfoService;

    /**
     * 生成订单的一系列附属表
     * @param orderJson  订单的信息
     */
    @RabbitListener(queues = {RabbitMQConfig.CREATE_ORDER_ITEM_QUEUE})
    public void createOrderItem(String orderJson, Channel channel, Message message) throws IOException {
        OrderEntity order = JSON.parseObject(orderJson, OrderEntity.class);

        try {
            OrderItemEntity orderItemEntity = null;
            for (long spuId : order.getSpuIds()) {
                if (spuId == 0) continue;
                RespBean respBean = spuInfoFeign.getSpuInfoVo(spuId);
                Integer code = (Integer) respBean.get("code");
                if ( respBean == null || !code.equals(200) ){
                    throw new RRException("OpenFeign get spuInfoVo is error code: {}", code);
                }
                SpuInfoVo spuInfoVo = JSON.parseObject((String) respBean.get("data"), SpuInfoVo.class);
                if ( spuInfoVo == null ){
                    // 商品失效，订单全部回滚,库存也会滚
                    log.info("OpenFeign get spuInfoVo is error : {}", spuId);
                    throw new RRException("OpenFeign get spuInfoVo is error");
                }
                orderItemEntity = new OrderItemEntity();
                orderItemEntity.setOrderId(order.getId());  // 设置订单id
                orderItemEntity.setOrderSn(order.getOrderSn());  // 设置订单号
                orderItemEntity.setSpuId(spuId);   // 设置spuId

                orderItemEntity.setSpuName(spuInfoVo.getSpuName());   // 设置SPUName
                orderItemEntity.setSpuDetail(spuInfoVo.getSpuDetail());
                orderItemEntity.setSpuPic(spuInfoVo.getSpuPic());   // 设置商品图片s

                orderItemEntity.setCategoryId(spuInfoVo.getCategoryId());  // 设置分类id
                orderItemEntity.setSpuBrand(spuInfoVo.getBrand());  // 设置品牌

                orderItemEntity.setSkuId(spuInfoVo.getSkuId());  // 设置skuId
                orderItemEntity.setSkuName(spuInfoVo.getSkuName());  // 设置skuName
                orderItemEntity.setSkuPic(spuInfoVo.getSkuPic());  // 设置sku照片
                orderItemEntity.setSkuPrice(spuInfoVo.getSkuPrice()); // 设置价格
                orderItemEntity.setSkuQuantity(1);  // 购买数量都为1，二手商品限一件

                orderItemEntity.setGiftGrowth(OrderServiceImpl.GROWTH);  // 设置成长值，，，统一不麻烦，哈哈哈
                orderItemEntity.setSkuAttrsVals(spuInfoVo.getAttrValues());  // 设置属性值
                orderItemService.save(orderItemEntity);
            }
            RespBean memberIds = spuInfoFeign.getMemberIds(order.getSpuIds());
            FeignProductVo memberInfo = JSON.parseObject((String) memberIds.get("data"), FeignProductVo.class);
            String text = null;

            // 给商品发布者用户推送站内信,表明商品已经被购买
            for ( int i = 0 ; i < memberInfo.getMemberIds().length ; i ++ ){
                text = "<mark style='background-color: #ef4400; color: #ffffff'>慕阳二手商城：</mark> <br>&nbsp;&nbsp;亲爱的 <mark style='background-color: #ef4400; color: #ffffff'>" + memberInfo.getNames()[i] + "</mark> <br>&nbsp;&nbsp;您的商品 <mark style='background-color: #ef4400; color: #ffffff'>"
                        + memberInfo.getProductNames()[i] + " </mark> 已被 <mark style='background-color: #ef4400; color: #ffffff'>" + order.getMemberUsername() + "</mark> 购买!";
                sendMessaging(String.valueOf(memberInfo.getMemberIds()[i]), text);
            }

            // 告知购买者，订单生成成功
            text =  "<mark style='background-color: #ef4400; color: #ffffff'>慕阳二手商城：</mark><br>&nbsp;&nbsp; 亲爱的 <mark style='background-color: #ef4400; color: #ffffff'>" + order.getMemberUsername() + " </mark> " +
                    "<br>&nbsp;&nbsp;您的订单 <mark style='background-color: #ef4400; color: #ffffff'> " + order.getOrderSn() + "</mark>已经生成~";
            sendMessaging(String.valueOf(order.getMemberId()), text);

            // 双方建立联系
            ConnectionVo vo = null;
            String jsonString = null;
            for ( int i = 0 ; i < memberInfo.getMemberIds().length ; i ++){
                vo = new ConnectionVo();
                vo.setMembreId(order.getMemberId());
                vo.setReceiveMemberId(memberInfo.getMemberIds()[i]);
                jsonString = JSON.toJSONString(vo);
                rabbitTemplate.convertAndSend("CONNECTION-MEMBER-QUEUE", jsonString);
            }

        } catch (RuntimeException e) {
            // 释放库存
            rollbackSaleCount(order.getSpuIds());

            // 创建订单失败，删除订单，真实删除
            orderService.removeById(order);
            redisTemplate.delete("order:" + order.getOrderSn());

            // 告知用户订单生成失败
            String text = "<mark style='background-color: #ef4400; color: #ffffff'>慕阳二手商城：</mark><br>&nbsp;&nbsp;亲爱的 <mark style='background-color: #ef4400; color: #ffffff'>" + order.getMemberUsername() + " </mark> " +
                    "<br>&nbsp;&nbsp;您在生成订单 <mark style='background-color: #ef4400; color: #ffffff'> " + order.getOrderSn() + "</mark> 时发生错误，请重新购买~~";
            sendMessaging(String.valueOf(order.getMemberId()), text);

            e.printStackTrace();
            throw new RRException("订单生成失败");
        } finally {
            log.info("生成列附属表进行手动签收");
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }

    }


    /**
     * 监听死信队列，进行订单操作
     *  判断订单的状态，如果订单状态不为0，那么就交付订单
     *  如果订单状态未0，则释放库存，并回滚事务
     * @param orderSn
     * @param channel
     * @param message
     */
    @RabbitListener(queues = {RabbitMQConfig.SHITOU_CLOSE_QUEUE})
    public void listenOrderClose(String orderSn, Channel channel, Message message)  {
        // 时间到达后，判断订单状态是否进行了支付
        // status '订单状态【0->待付款；1->待发货；2->已发货；3->已完成；4->已关闭；5->无效订单】',
        try {
            OrderEntity order = (OrderEntity) redisTemplate.opsForValue().get("order:" + orderSn);
            if ( order == null ){   // 默认支付失败
                log.error("the order pay is error: {}", orderSn);
                throw new RRException("订单支付异常，没有订单数据");
            }
            // 商品已经进行了支付成功了
            if (order.getStatus() != 0 && order.getStatus() > 0) {
                // TODO 支付成功后，做的一些操作

                log.info("the order pay is success: {}", orderSn);
            } else if (order.getStatus() == 0) {
                // 支付失败，进行关闭订单和释放库存
                reconfirmProduct(order);
                rollbackSaleCount(order.getSpuIds());

                // 删除（关闭）订单,伪删除
                order.setDeleteStatus(1);   // 删除订单
                order.setModifyTime(new Date());  // 修改时间
                orderService.updateById(order);   // 更新订单
                // 支付失败，删除reidis中的，，，自动收货伪null返回
                redisTemplate.delete("order:"+ orderSn);


                // 给发布商品的用户发送站内信，售卖失败,用户支付未成功
                List<OrderItemEntity> orderItemList = orderItemService.list(new QueryWrapper<OrderItemEntity>()
                        .eq("order_sn", orderSn));
                long[] spuIds = order.getSpuIds();
                RespBean memberIds = spuInfoFeign.getMemberIds(spuIds);
                FeignProductVo memberInfo = JSON.parseObject((String) memberIds.get("data"), FeignProductVo.class);
                String text = null;

                for ( int i = 0 ; i < memberInfo.getMemberIds().length ; i ++){
                    text = "<mark style='background-color: #ef4400; color: #ffffff'>慕阳二手商城：</mark> <br>&nbsp;&nbsp;亲爱的 <mark style='background-color: #ef4400; color: #ffffff'>" + memberInfo.getNames()[i] + "</mark> <br>&nbsp;&nbsp;您的商品 <mark style='background-color: #ef4400; color: #ffffff'>"
                            + memberInfo.getProductNames()[i] + " </mark> 没有被按时支付，已被退回";
                    sendMessaging(String.valueOf(memberInfo.getMemberIds()[i]), text);
                }

                // 给购买者推送支付超时信息
                text = "<mark style='background-color: #ef4400; color: #ffffff'>慕阳二手商城：</mark> <br>&nbsp;&nbsp;亲爱的 <mark style='background-color: #ef4400; color: #ffffff'> " + order.getMemberUsername() + "</mark> <br>&nbsp;&nbsp;您的订单 <mark style='background-color: #ef4400; color: #ffffff'>"
                        + orderSn + "</mark> 没有按时支付，该订单已经失效~~~请重新购物";
                sendMessaging(String.valueOf(order.getMemberId()), text);

                log.error("the order pay is defeated: {}", orderSn);
            }
        } catch (Exception e){
            log.info("自动关单时，支付异常");
            redisTemplate.delete("order:"+ orderSn);
        } finally {
            try {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                log.info("订单支付延时队列进行了签收");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }


    /**
     * 用户在订单结束前进行了订单的支付，
     *      订单支付成功后，进行一系列的操作
     * @param notiryVo
     * @param channel
     * @param message
     */
    @RabbitListener(queues = {RabbitMQConfig.UPDATE_ORDER_QUEUE})
    public void paySuccessUpdateOrder(String notiryVo, Channel channel, Message message) {
        PayNotifyVo payNotifyVo = (PayNotifyVo) JSON.parseObject(notiryVo, PayNotifyVo.class);
        String orderSn = payNotifyVo.getOrderToken();
        OrderEntity order = (OrderEntity) redisTemplate.opsForValue().get("order:" + orderSn);

        // 将支付信息存入redis中，用户申请退款用
        payNotifyVo.setMemberId(String.valueOf(order.getMemberId()));
        payNotifyVo.setUsername(order.getMemberUsername());
        String jsonString1 = JSON.toJSONString(payNotifyVo);
        redisTemplate.opsForValue().set("notiry:"+orderSn, jsonString1);

        try{
            // redis中的订单已经失效
            if ( order == null ){
                log.info("order is null : {}", payNotifyVo.getOrderToken());
                //  订单为空，支付订单回退
                rabbitTemplate.convertAndSend("ORDER-REFOND-QUEUE", notiryVo);
                log.error("当前订单已经失效或者已经完成支付，订单已经回滚");
                sendPayError(String.valueOf(order.getMemberId()), orderSn, order.getMemberUsername());
                throw new RRException("订单发生异常，请联系客服");
            }
            // 订单校验
            if ( !order.getOrderSn().equals(orderSn)) {
                //  订单回滚
                rabbitTemplate.convertAndSend("ORDER-REFOND-QUEUE", notiryVo);
                log.error("当前支付订单出错，订单已经回滚");
                sendPayError(String.valueOf(order.getMemberId()), orderSn, order.getMemberUsername());
                throw new RRException("订单发生异常，请联系客服");
            }
            // 支付金额进行比对
            BigDecimal totalAmount = BigDecimal.valueOf(Double.valueOf(String.valueOf(order.getTotalAmount())));
            BigDecimal totalAmount1 = BigDecimal.valueOf(Double.valueOf(payNotifyVo.getTotalAmount()));
            BigDecimal payAmount = BigDecimal.valueOf(Double.valueOf(String.valueOf(order.getPayAmount())));
            BigDecimal buyerPayAmount = BigDecimal.valueOf(Double.valueOf(payNotifyVo.getBuyerPayAmount()));
            if ( !totalAmount1.equals(totalAmount)  || !payAmount.equals(buyerPayAmount) ){
                rabbitTemplate.convertAndSend("ORDER-REFOND-QUEUE", notiryVo);
                log.error("当前支付订单金额支付出错，订单已经回滚");
                sendPayError(String.valueOf(order.getMemberId()), orderSn, order.getMemberUsername());
                throw new RRException("订单发生异常，请联系客服");
            }

            // 更新订单信息
            Date date = new Date();
            order.setPaymentTime(date);   // 支付时间
            order.setModifyTime(date);   // 修改时间
            order.setDeliveryTime(date);   // 发货时间，默认当时发货，二手商品最好快速进行交易
            // 0-待付款 1-待发货 2-待收货 3-已收货 4-已完成 5-待评价 6-无效订单
            order.setStatus(2);  // 付款成功默认发货,2-待收货
            order.setPayAmount(buyerPayAmount);   // 重新设置支付金额
            orderService.updateById(order);
            log.info("支付成功，更新订单");

            // 更新redis中的order
            redisTemplate.opsForValue().set("order:" + orderSn, order);

            // 发送延时消息，对该订单进行监控，监控该订单的自动收货时间，，，如果订单被用户确认，那么关闭延时消息，自动ack，收获状态等
            rabbitTemplate.convertAndSend(RabbitMQConfig.ORDER_AUTOCONFIRM_TTL_QUEUE, orderSn);
            log.info("自动收货开始监控");


            //  创建支付信息表
            PaymentInfoEntity paymentInfo = new PaymentInfoEntity();
            paymentInfo.setOrderId(order.getId());  // 设置订单id
            paymentInfo.setOrderSn(order.getOrderSn());  // 设置订单号
            paymentInfo.setAlipayTradeNo(payNotifyVo.getTradeNo()); // 支付宝交易流水号
            paymentInfo.setTotalAmount(BigDecimal.valueOf(Double.valueOf(payNotifyVo.getTotalAmount())));  // 支付金额
            paymentInfo.setSubject(payNotifyVo.getSubject());   // 支付内容
            paymentInfo.setPaymentStatus(payNotifyVo.getTradeStatus());  // 支付状态
            paymentInfo.setCreateTime(new Date());   // 创建时间
            paymentInfo.setConfirmTime(new Date());  // 确认支付时间
            paymentInfo.setCallbackContent(JSON.toJSONString(payNotifyVo));  // 回调内容
            paymentInfo.setCallbackTime(new Date());  // 回调时间
            paymentInfoService.save(paymentInfo);


            String text = null;

            // 给发布商品会员推送消息
            List<OrderItemEntity> orderItemList = orderItemService.list(new QueryWrapper<OrderItemEntity>()
                    .eq("order_sn", orderSn));
            long[] spuIds = order.getSpuIds();
            RespBean memberIds = spuInfoFeign.getMemberIds(spuIds);
            FeignProductVo memberInfo = JSON.parseObject((String) memberIds.get("data"), FeignProductVo.class);
            for ( int i = 0 ; i < memberInfo.getMemberIds().length ; i ++){
                text = "<mark style='background-color: #ef4400; color: #ffffff'>慕阳二手商城：</mark> <br>&nbsp;&nbsp;亲爱的 <mark style='background-color: #ef4400; color: #ffffff'>" + memberInfo.getNames()[i] + "</mark> 您的商品 <mark style='background-color: #ef4400; color: #ffffff'>"
                        + memberInfo.getProductNames()[i] + " </mark> 已被 <mark style='background-color: #ef4400; color: #ffffff'>" + order.getMemberUsername() + "</mark> 购买并支付成功!";
                sendMessaging(String.valueOf(memberInfo.getMemberIds()[i]), text);
            }

            // 给购买商品的会员推送消息
            text =  "<mark style='background-color: #ef4400; color: #ffffff'>慕阳二手商城：</mark> <br>&nbsp;&nbsp;亲爱的 <mark style='background-color: #ef4400; color: #ffffff'>" + order.getMemberUsername() + "</mark> <br>&nbsp;&nbsp;您的订单 <mark style='background-color: #ef4400; color: #ffffff'>"
                    + orderSn + "</mark> 已经被支付成功!";
            sendMessaging(String.valueOf(order.getMemberId()), text);


        } catch (Exception e){
            // 发生异常，通知购买用户支付失败，是否重新支付
            String text =  "<mark style='background-color: #ef4400; color: #ffffff'>慕阳二手商城：</mark> <br>&nbsp;&nbsp;亲爱的 <mark style='background-color: #ef4400; color: #ffffff'>" + order.getMemberUsername() + "</mark> <br>&nbsp;&nbsp;您的订单 <mark style='background-color: #ef4400; color: #ffffff'>"
                    + orderSn + "</mark> 支付失败！！!";
            sendMessaging(String.valueOf(order.getMemberId()), text);

            e.printStackTrace();
            log.error("update order is null: {},{}",payNotifyVo.getOrderToken(), e.getMessage());
        } finally {
            try {
                // 手动ack
                log.info("支付时，进行了手动签收");
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            } catch (IOException e) {
                throw new RRException(e.getMessage());
            }
        }

    }


    /**
     * 监听死信队列，自动收货时间到达，用户没有进行收货，
     *      则进行订单自动收货的操作
     * @param msg
     * @param channel
     * @param message
     */
    @RabbitListener(queues = {RabbitMQConfig.ORDER_AUTOCONFIRM_CLOSE_QUEUE})
    public void listenOrderAutoConfirm(String orderSn, Channel channel, Message message){

//        OrderEntity order = orderService.getOne(new QueryWrapper<OrderEntity>().eq("order_sn", orderSn));
        OrderEntity order = (OrderEntity) redisTemplate.opsForValue().get("order:" + orderSn);

        try {

            if ( order == null ){
                log.info("订单因为支付失败或者超时导致订单没有后续，故收货失败!!");
                throw new RRException("订单因为支付失败或者超时导致订单没有后续，故收货失败!!");
            }

            // 状态为删除和已经完成了的订单,,,,那么直接返回，用户以及进行了手动收货
            if (order.getDeleteStatus() != 0 || order.getStatus() >= 4) {
                log.info("订单被删除或者已经完成，自动收货队列进行了手动签收");
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                return ;
            }

            // 真正的减库存,发送消息到shitou-product服务进行操作
            String spuIdsString = JSON.toJSONString(order.getSpuIds());
            rabbitTemplate.convertAndSend("DECREMENT-SALECOUNT", spuIdsString);
            log.info("减库存");

            // 发送消息给会员，给用户提供成长值和一些列操作
            MemberVo memberVo = new MemberVo();
            memberVo.setMemberId(order.getMemberId());
            memberVo.setGrowth(order.getGrowth());
            memberVo.setPayAmount(order.getPayAmount());
            memberVo.setSpuIds(order.getSpuIds());
            String jsonString = JSON.toJSONString(memberVo);
            rabbitTemplate.convertAndSend("MEMBER-OPTION-QUEUE", jsonString);
            log.info("成长值");

            Date date = new Date();
            order.setModifyTime(date);   // 修改时间
            order.setReceiveTime(date);  // 收货时间
            order.setConfirmStatus(1);  // 收货状态
            // 0-待付款 1-待发货 2-待收货 3-已收货 4-已完成 5-待评价 6-无效订单
            order.setStatus(4);   // 订单状态，4 -> 已收货
            orderService.updateById(order);

            // 给发布商品会员推送消息
            List<OrderItemEntity> orderItemList = orderItemService.list(new QueryWrapper<OrderItemEntity>()
                    .eq("order_sn", orderSn));
            long[] spuIds = order.getSpuIds();
            RespBean memberIds = spuInfoFeign.getMemberIds(spuIds);
            FeignProductVo memberInfo = JSON.parseObject((String) memberIds.get("data"), FeignProductVo.class);
            String text = null;
            for ( int i = 0 ; i < memberInfo.getMemberIds().length ; i ++){
                text = "<mark style='background-color: #ef4400; color: #ffffff'>慕阳二手商城：</mark> <br>&nbsp;&nbsp;亲爱的 <mark style='background-color: #ef4400; color: #ffffff'>" + memberInfo.getNames()[i] + "</mark><br>&nbsp;&nbsp; 您的商品 <mark style='background-color: #ef4400; color: #ffffff'>"
                        + memberInfo.getProductNames()[i] + " </mark> 已经被 <mark style='background-color: #ef4400; color: #ffffff'>" + order.getMemberUsername() + "</mark> 购买并自动收货成功，!";
                sendMessaging(String.valueOf(memberInfo.getMemberIds()[i]), text);
            }

            // 给购买商品的会员推送消息
            text =  "<mark style='background-color: #ef4400; color: #ffffff'>慕阳二手商城：</mark> <br>&nbsp;&nbsp;亲爱的 <mark style='background-color: #ef4400; color: #ffffff'>" + order.getMemberUsername() + "</mark> <br>&nbsp;&nbsp;您的订单 <mark style='background-color: #ef4400; color: #ffffff'>"
                    + orderSn + "</mark> 已经完成交易，自动收货!";
            sendMessaging(String.valueOf(order.getMemberId()), text);

            log.info("用户自动收获成功: {}",orderSn);

        } catch (IOException e){
            log.error("在自动收货的时候,发生了异常: {}", orderSn);

        } finally {
            // 删除notiry
            redisTemplate.delete("notity:"+orderSn);

            // 不管收货是否成功都要将redis中的订单信息删除
            redisTemplate.delete("order:" + orderSn);
            try {
                log.info("自动收货队列进行了手动签收");
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            } catch (IOException ex) {
                throw new RRException(ex.getMessage());
            }
        }
    }


    /**
     * 释放库存
     * @param spuIds
     */
    public void rollbackSaleCount(long[] spuIds){

        for (long spuId : spuIds) {
            String productToken = String.valueOf(new Sha256Hash(String.valueOf(spuId), AllSaltEnum.SALT.getSalt()));
            redisTemplate.opsForValue().set("saleCount:" + productToken, 0);

            // 将索引中的状态设置为   启用
            rabbitTemplate.convertAndSend("PRODUCT-RELEASE-QUEUE", spuId);
        }
    }


    /**
     * 在做所有的更新之前都需要进行商品的再次确认，因为再支付过程中
     *      用户可能会对订单下的商品进行一些修改
     *      也可以不用，但是为了以防万一
     * @param order
     */
    public void reconfirmProduct(OrderEntity order){
        List<Long> list = new ArrayList<>();
        List<OrderItemEntity> orderItemList = orderItemService.list(new QueryWrapper<OrderItemEntity>()
                .eq("order_sn", order.getOrderSn()).eq("status", 1));
        for (OrderItemEntity orderItemEntity : orderItemList) {
            list.add(orderItemEntity.getSpuId());
        }

        long[] newSpuIds = new long[list.size()];
        for(int i = 0 ;i < list.size() ; i ++){
            newSpuIds[i] = list.get(i).longValue();
        }
        order.setSpuIds(newSpuIds);
        redisTemplate.opsForValue().set("order:" + order.getOrderSn(), order);
    }


    /**
     * 发送站站内信通知
     * @param order
     * @param text
     */
    public void sendMessaging(String to, String text){
        MessageVo messageVo = new MessageVo();
        messageVo.setTo(to);
        messageVo.setFrom("0");
        messageVo.setDate(new Date());
        messageVo.setText(text);
        String jsonString = JSON.toJSONString(messageVo);
        rabbitTemplate.convertAndSend("SEND-MESSAGING-QUEUE", jsonString);
    }


    /**
     * 支付失败异常站内信推送
     * @param to
     */
    public void sendPayError(String to, String orderSn, String username){
        String text =  "<mark style='background-color: #ef4400; color: #ffffff'>慕阳二手商城：</mark> 亲爱的 <mark style='background-color: #ef4400; color: #ffffff'>" + username + "</mark 您的订单： <mark style='background-color: #ef4400; color: #ffffff'>"
                + orderSn + "</mark> 在支付时产生错误，产生的费用已经原路退回~~<br> 您也可以重新支付，如果任然出现问题请联系管理员!!";
        sendMessaging(to, text);
    }


    /**
     * 获取商品名称map
     * @param orderSn
     * @return
     */
    public Map<Long, String> getProductNames(String orderSn){
        Map<Long, String> map = new HashMap<>();
        List<OrderItemEntity> order_sn = orderItemService.list(new QueryWrapper<OrderItemEntity>()
                .eq("order_sn", orderSn));
        for (OrderItemEntity orderItemEntity : order_sn) {
            map.put(orderItemEntity.getSpuId(), orderItemEntity.getSpuName());
        }
        return map;
    }


    /**
     * 退款成功后，修改订单信息
     * @param notiry
     * @param channel
     * @param message
     */
    @RabbitListener(queues = {RabbitMQConfig.REFUND_UPDATE_ORDER_INFO})
    public void refundUpdateOrderQueue(String notiry, Channel channel, Message message){
        try {
            // 判断当前订单是否已经完成了,
            // 退款信息
            PayNotifyVo notiryVo = JSON.parseObject(notiry, PayNotifyVo.class);
            OrderEntity order = orderService.getOne(new QueryWrapper<OrderEntity>().eq("order_sn", notiryVo.getOrderToken()));
            Integer status = order.getStatus();
            // 买家已经完成了签收，完成了交易!!!
            if( status >= 4 || status < 1){
                return;
            }
            // 判断当前金额
            // 总的信息
            PayNotifyVo allNotifyVo = JSON.parseObject((String) redisTemplate.opsForValue().get("notiry:"+notiryVo.getOrderToken()),PayNotifyVo.class);
            Double totalAmount = Double.valueOf(allNotifyVo.getTotalAmount());
            Double refundTotalAmount = Double.valueOf(notiryVo.getTotalAmount());

            // 将订单状态设置为 0
            order.setStatus(0);
            order.setModifyTime(new Date());
            orderService.updateById(order);

            // 构建信息
            DeleteOrderVo deleteOrderVo = new DeleteOrderVo();
            deleteOrderVo.setOrderSn(allNotifyVo.getOrderToken());
            deleteOrderVo.setOrderItemId(Long.parseLong(notiryVo.getOrderItemId()));
            deleteOrderVo.setMemberId(Long.parseLong(notiryVo.getMemberId()));

            // 修改订单信息，或者将订单设置未无效订单,,,在这里已经进行了库存的释放
            orderService.deleteOrder(deleteOrderVo);

            // TODO 修改用户成长值,,,由于自动关单时才修改成长值，故，此处舍弃，暂留


            // TODO 释放库存，由于自动关单时才修改库存，故，此处舍弃，暂留


            // 已经退完款项
            if ( totalAmount - refundTotalAmount <= 0 ){
                redisTemplate.delete("notiry:"+allNotifyVo.getOrderToken());
            }
        } catch (Exception e){
            log.info(e.getMessage());
        } finally {
            try {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            } catch (IOException e) {
                throw new RRException("在自动ack时，发生异常");
            }
        }


    }

}
